from PyQt6.QtWidgets import (
    QMainWindow, QTabWidget, QSplitter, QStatusBar,
    QFileDialog, QMessageBox, QInputDialog, QDialog,
    QVBoxLayout, QLabel, QLineEdit, QPushButton, QHBoxLayout
)
from PyQt6.QtCore import Qt, QSize, QUrl
from PyQt6.QtGui import QIcon, QAction, QDesktopServices

from widgets.db_tree import DatabaseTree
from ui.sql_editor import SQLEditor
from widgets.status_bar import EnhancedStatusBar
from ui.connection_dialog import ConnectionDialog
from core.connection import ConnectionManager
import os
import sys
import pandas as pd


def resource_path(relative_path):
    if hasattr(sys, '_MEIPASS'):
        return os.path.join(sys._MEIPASS, relative_path)
    return os.path.join(os.path.abspath("."), relative_path)


class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        self.setWindowTitle("PyNavicat")
        self.resize(1200, 800)
        self.setWindowIcon(QIcon("resources/icons/app.png"))  # 设置应用图标

        # 连接管理器
        self.connection_manager = ConnectionManager()

        # 中心部件
        self.splitter = QSplitter(Qt.Orientation.Horizontal)

        # 左侧数据库树
        self.db_tree = DatabaseTree(self.connection_manager)
        self.db_tree.connection_selected.connect(self.on_connection_selected)
        self.db_tree.table_selected.connect(self.on_table_selected)
        self.splitter.addWidget(self.db_tree)

        # 右侧标签页
        self.tab_widget = QTabWidget()
        self.tab_widget.setTabsClosable(True)
        self.tab_widget.tabCloseRequested.connect(self.close_tab)

        self.add_sql_editor()
        self.splitter.addWidget(self.tab_widget)
        self.splitter.setSizes([250, 950])
        self.setCentralWidget(self.splitter)

        # 状态栏
        self.status_bar = EnhancedStatusBar()
        self.setStatusBar(self.status_bar)

        # 菜单栏
        self.create_menus()
        self.apply_styles()
        self.load_connections()

    # ------------- 其余方法保持不变 -------------
    def apply_styles(self):
        try:
            with open("resources/styles/light.qss", "r") as f:
                self.setStyleSheet(f.read())
        except Exception:
            pass

    def load_connections(self):
        conn_id = self.connection_manager.add_connection({
            "name": "本地MySQL",
            "type": "mysql",
            "host": "localhost",
            "port": 3306,
            "user": "root",
            "password": "root",
            "database": ""
        })

        self.db_tree.populate_tree()

    # ------------------------------------------------------------
    #  菜单栏：使用统一的 create_action 辅助函数，避免重复代码
    # ------------------------------------------------------------
    def create_action(self,
                      parent_menu,
                      icon_path: str,
                      text: str,
                      shortcut: str | None = None,
                      triggered=None):
        action = QAction(QIcon(icon_path), text, self) if icon_path else QAction(text, self)
        if shortcut:
            action.setShortcut(shortcut)
        if triggered:
            action.triggered.connect(triggered)
        parent_menu.addAction(action)
        return action

    # ------------------------------------------------------------
    #  创建所有菜单
    # ------------------------------------------------------------
    def create_menus(self):
        mb = self.menuBar()

        # 文件
        file_menu = mb.addMenu("文件")
        self.create_action(file_menu, "resources/icons/new_connection.png",
                           "新建连接", triggered=self.new_connection)
        self.create_action(file_menu, "resources/icons/disconnect.png",
                           "断开连接", triggered=self.disconnect)
        file_menu.addSeparator()
        self.create_action(file_menu, "resources/icons/new_query.png",
                           "新建查询", "Ctrl+N", triggered=self.new_query)
        self.create_action(file_menu, "resources/icons/save.png",
                           "保存查询", "Ctrl+S", triggered=self.save_query)
        file_menu.addSeparator()
        self.create_action(file_menu, "resources/icons/import.png",
                           "导入数据", triggered=self.import_data)
        self.create_action(file_menu, "resources/icons/export.png",
                           "导出数据", triggered=self.export_data)
        file_menu.addSeparator()
        self.create_action(file_menu, "resources/icons/backup.png",
                           "备份数据库", triggered=self.backup_database)
        self.create_action(file_menu, "resources/icons/restore.png",
                           "恢复数据库", triggered=self.restore_database)
        file_menu.addSeparator()
        self.create_action(file_menu, None, "退出", "Ctrl+Q", triggered=self.close)

        # 编辑
        edit_menu = mb.addMenu("编辑")
        self.create_action(edit_menu, "resources/icons/undo.png",
                           "撤销", "Ctrl+Z", triggered=self.undo)
        self.create_action(edit_menu, "resources/icons/redo.png",
                           "重做", "Ctrl+Y", triggered=self.redo)
        edit_menu.addSeparator()
        self.create_action(edit_menu, "resources/icons/cut.png",
                           "剪切", "Ctrl+X", triggered=self.cut)
        self.create_action(edit_menu, "resources/icons/copy.png",
                           "复制", "Ctrl+C", triggered=self.copy)
        self.create_action(edit_menu, "resources/icons/paste.png",
                           "粘贴", "Ctrl+V", triggered=self.paste)

        # 查看
        view_menu = mb.addMenu("查看")
        toolbar_action = view_menu.addAction("工具栏")
        toolbar_action.setCheckable(True)
        toolbar_action.setChecked(True)
        toolbar_action.triggered.connect(self.toggle_toolbar)
        statusbar_action = view_menu.addAction("状态栏")
        statusbar_action.setCheckable(True)
        statusbar_action.setChecked(True)
        statusbar_action.triggered.connect(self.toggle_statusbar)
        view_menu.addSeparator()
        dark_action = view_menu.addAction("深色主题")
        dark_action.setCheckable(True)
        dark_action.triggered.connect(lambda: self.set_theme('dark'))
        light_action = view_menu.addAction("浅色主题")
        light_action.setCheckable(True)
        light_action.setChecked(True)
        light_action.triggered.connect(lambda: self.set_theme('light'))
        self.theme_actions = {'dark': dark_action, 'light': light_action}

        # 工具
        tools_menu = mb.addMenu("工具")
        tools_menu.addAction("用户管理")
        tools_menu.addAction("服务器监控")
        tools_menu.addSeparator()
        setting_action = tools_menu.addAction("选项")
        setting_action.triggered.connect(self.show_settings)


        # SQL
        sql_menu = mb.addMenu("SQL")
        self.create_action(sql_menu, "resources/icons/run.png",
                           "执行 (F5)", "F5", triggered=self.execute_sql)
        self.create_action(sql_menu, "resources/icons/run_current.png",
                           "执行当前语句 (Ctrl+Enter)", "Ctrl+Return",
                           triggered=self.execute_current_sql)
        sql_menu.addSeparator()
        self.create_action(sql_menu, "resources/icons/format.png",
                           "格式化 (Ctrl+Shift+F)", "Ctrl+Shift+F",
                           triggered=self.format_sql)

        # 帮助
        help_menu = mb.addMenu("帮助")
        help_doc = help_menu.addAction("文档")
        help_doc.triggered.connect(self.show_help_doc)
        check_update_action =help_menu.addAction("检查更新")
        check_update_action.triggered.connect(self.check_update)
        help_menu.addSeparator()
        about_action = help_menu.addAction("关于")
        about_action.triggered.connect(self.show_about_dialog)

    def show_about_dialog(self):
        QMessageBox.information(self, "关于 PyNavicat", "PyNavicat\n\n一个简洁易用的数据库管理工具。\n\n作者：草上飞\n版本：1.0.0\n\n如有建议或问题，欢迎反馈！")

    def check_update(self):
        QMessageBox.information(self, "检查更新", "当前版本为1.0.0，已是最新版本。")

    def show_help_doc(self):
        QDesktopServices.openUrl(QUrl("https://gitee.com/brisklan/py-navicate"))


    def show_settings(self):
        dlg = QDialog(self)
        dlg.setWindowTitle("选项设置")
        dlg.setMinimumWidth(300)
        layout = QVBoxLayout(dlg)

        # 示例配置项
        label1 = QLabel("默认每页显示行数：")
        lineedit1 = QLineEdit()
        lineedit1.setPlaceholderText("如 100")
        layout.addWidget(label1)
        layout.addWidget(lineedit1)

        label2 = QLabel("主题：")
        lineedit2 = QLineEdit()
        lineedit2.setPlaceholderText("light/dark")
        layout.addWidget(label2)
        layout.addWidget(lineedit2)

        # 按钮
        btn_layout = QHBoxLayout()
        btn_ok = QPushButton("确定")
        btn_cancel = QPushButton("取消")
        btn_layout.addWidget(btn_ok)
        btn_layout.addWidget(btn_cancel)
        layout.addLayout(btn_layout)

        btn_ok.clicked.connect(dlg.accept)
        btn_cancel.clicked.connect(dlg.reject)

        if dlg.exec() == QDialog.DialogCode.Accepted:
            # 这里可以保存配置
            QMessageBox.information(self, "设置", "设置已保存！")


    def add_sql_editor(self, title="查询", content=""):
        editor = SQLEditor(self, self.connection_manager)
        if content:
            editor.editor.setText(content)
        self.tab_widget.addTab(editor, title)
        self.tab_widget.setCurrentWidget(editor)
        return editor

    def close_tab(self, index):
        if self.tab_widget.count() > 1:
            self.tab_widget.removeTab(index)

    def new_connection(self):
        dlg = ConnectionDialog(self)
        if dlg.exec() == QDialog.DialogCode.Accepted:
            info = dlg.get_connection_info()
            self.connection_manager.add_connection(info)
            self.db_tree.populate_tree()
            self.status_bar.show_message(f"已添加连接: {info['name']}")

    def new_query(self):
        self.add_sql_editor()

    def save_query(self):
        cur = self.tab_widget.currentWidget()
        if isinstance(cur, SQLEditor):
            cur.save_sql()

    def execute_sql(self):
        cur = self.tab_widget.currentWidget()
        if isinstance(cur, SQLEditor):
            cur.execute_query()

    def execute_current_sql(self):
        cur = self.tab_widget.currentWidget()
        if isinstance(cur, SQLEditor):
            cur.execute_current_query()

    def format_sql(self):
        cur = self.tab_widget.currentWidget()
        if isinstance(cur, SQLEditor):
            cur.format_sql()

    def import_data(self):
        path, _ = QFileDialog.getOpenFileName(
            self, "选择导入文件", "",
            "CSV Files (*.csv);;Excel Files (*.xlsx);;JSON Files (*.json);;All Files (*)"
        )
        if path:
            self.status_bar.show_message(f"正在导入: {os.path.basename(path)}")

    def export_data(self):
        cur = self.tab_widget.currentWidget()
        if not isinstance(cur, SQLEditor):
            QMessageBox.warning(self, "导出", "请先激活一个SQL编辑器窗口并执行查询！")
            return
        df = getattr(cur, 'last_result_df', None)
        if df is None or df.empty:
            QMessageBox.warning(self, "导出", "没有可导出的数据，请先执行查询！")
            return
        # 弹出格式选择
        formats = ["CSV", "Excel", "JSON", "SQL"]
        fmt, ok = QInputDialog.getItem(self, "选择导出格式", "格式：", formats, 0, False)
        if not ok:
            return
        # 选择文件保存路径
        ext_map = {"CSV": ".csv", "Excel": ".xlsx", "JSON": ".json", "SQL": ".sql"}
        filter_map = {"CSV": "CSV Files (*.csv)", "Excel": "Excel Files (*.xlsx)", "JSON": "JSON Files (*.json)", "SQL": "SQL Files (*.sql)"}
        ext = ext_map[fmt]
        file_filter = filter_map[fmt]
        path, _ = QFileDialog.getSaveFileName(self, f"保存导出文件", f"导出数据{ext}", file_filter)
        if not path:
            return
        try:
            if fmt == "CSV":
                df.to_csv(path, index=False, encoding='utf-8-sig')
            elif fmt == "Excel":
                df.to_excel(path, index=False)
            elif fmt == "JSON":
                df.to_json(path, orient='records', force_ascii=False)
            elif fmt == "SQL":
                table = '导出表'
                with open(path, 'w', encoding='utf-8') as f:
                    for _, row in df.iterrows():
                        cols = ', '.join([f'`{c}`' for c in df.columns])
                        vals = ', '.join([repr(v) for v in row.values])
                        f.write(f"INSERT INTO {table} ({cols}) VALUES ({vals});\n")
            self.status_bar.show_message(f"导出成功: {path}")
        except Exception as e:
            QMessageBox.critical(self, "导出失败", str(e))

    def backup_database(self):
        QMessageBox.information(self, "备份数据库", "数据库备份功能")

    def restore_database(self):
        path, _ = QFileDialog.getOpenFileName(
            self, "选择备份文件", "",
            "SQL Files (*.sql);;Backup Files (*.bak);;All Files (*)"
        )
        if path:
            self.status_bar.show_message(f"正在从备份恢复: {os.path.basename(path)}")

    def disconnect(self):
        self.connection_manager.current_connection = None
        self.db_tree.populate_tree()
        self.status_bar.show_message("已断开当前连接")

    def on_connection_selected(self, conn_id):
        self.status_bar.show_message(f"已选择连接: {conn_id}")

    def on_table_selected(self, db_name, table_name):
        sql = f"SELECT * FROM `{db_name}`.`{table_name}` LIMIT 100;"
        editor = self.add_sql_editor(f"{db_name}.{table_name}", sql)
        editor.execute_query()

    # ---------------- 占位槽（根据需要自行实现） ----------------
    def undo(self):
        widget = self.focusWidget()
        if hasattr(widget, 'undo'):
            widget.undo()
        else:
            QMessageBox.information(self, "提示", "当前控件不支持撤销操作")

    def redo(self):
        widget = self.focusWidget()
        if hasattr(widget, 'redo'):
            widget.redo()
        else:
            QMessageBox.information(self, "提示", "当前控件不支持重做操作")

    def cut(self):
        widget = self.focusWidget()
        if hasattr(widget, 'cut'):
            widget.cut()
        else:
            QMessageBox.information(self, "提示", "当前控件不支持剪切操作")

    def copy(self):
        widget = self.focusWidget()
        if hasattr(widget, 'copy'):
            widget.copy()
        else:
            QMessageBox.information(self, "提示", "当前控件不支持复制操作")

    def paste(self):
        widget = self.focusWidget()
        if hasattr(widget, 'paste'):
            widget.paste()
        else:
            QMessageBox.information(self, "提示", "当前控件不支持粘贴操作")

    def toggle_toolbar(self, checked):
        # 这里假设有 self.toolbar，如果没有可自行实现
        if hasattr(self, 'toolbar'):
            self.toolbar.setVisible(checked)
        else:
            QMessageBox.information(self, "提示", "当前未实现工具栏控件。")

    def toggle_statusbar(self, checked):
        self.statusBar().setVisible(checked)

    def set_theme(self, theme):
        # 互斥选择
        for k, act in self.theme_actions.items():
            act.setChecked(k == theme)
        if theme == 'dark':
            try:
                qss_path = resource_path("resources/styles/dark.qss")
                with open(qss_path, "r", encoding="utf-8") as f:
                    self.setStyleSheet(f.read())
            except Exception:
                QMessageBox.warning(self, "主题", "未找到深色主题文件")
        else:
            try:
                with open("resources/styles/light.qss", "r") as f:
                    self.setStyleSheet(f.read())
            except Exception:
                self.setStyleSheet("")